import traceback
from abc import abstractmethod

from re_common.baselibrary.utils.basetime import BaseTime
from re_common.baselibrary.utils.core.mdeprecated import try_except2_async

from apps.crawler_platform.core_abs.downstepabs import ParaItems
from apps.crawler_platform.core_platform.core_down import CoreDownMixin
from apps.crawler_platform.core_platform.core_sql import CoreSqlMixin
from apps.crawler_platform.core_platform.downler import BaseDownStep
from apps.crawler_platform.core_platform.g_model import DealModel, CallBackModel
from apps.crawler_platform.core_callback import *

STATICA_HACK = False
# globals()['kcah_acitats'[::-1].upper()] = False
if STATICA_HACK:  # pragma: no cover
    null()


class BaseQKItems(ParaItems):

    def __init__(self):
        super(BaseQKItems, self).__init__()
        self.journal_rawid: str = ''


class BaseQKStep(BaseDownStep, CoreDownMixin):

    def __init__(self):
        super().__init__()
        self.err_tag = ""

        # ZCN:为保持结构一致性, 目前需要batch字段
        self.basetime = BaseTime()
        self.batchtime = self.basetime.get_beijin_date_strins()
        self.batch = self.batchtime[0:8] + "_" + self.batchtime[-6:]

    @try_except2_async(is_print=True)
    async def down(self):
        if self.pm.turn_page in [2, 1]:
            # 翻页下载，不管失败与否，翻页到最后，返回的状态由最后一个下载决定
            return await self.page_down()
        elif self.pm.turn_page == 3:
            # 该模式下 下载失败且有明确的code时会返回true，表示继续下载
            return await self.stat_down()
        elif self.pm.turn_page == 0:
            # 该下载模式下，会按顺序下载，某个keys下载失败会返回错误,且下次重新下载
            # 会全部下载，不会跳过(当然这里是指taskinfo 的多条配置之间的逻辑，单条
            # 翻页逻辑的跳过不归这里管)
            return await self.order_down()
        elif self.pm.turn_page == 4:
            return await self.deal_down()
        elif self.pm.turn_page in [5, 6]:
            return await self.multiple_page_down()
        else:
            raise Exception("异常 没有这种下载模式")

    async def my_task(self, table=""):
        """
        接入调用的task
        :return:
        """
        try:
            bools, err_info = await self.run_task()
            if not bools:
                bools_err, err_info_after = await self.err_collect(err_info, self.pm, self.batch, self.err_tag)
                return bools, err_info_after
            return bools, err_info

        except:
            await CoreSqlMixin.insert_errinfo(self.pm.task_name, self.pm.task_tag, self.pm.Id, self.batch,
                                              str(traceback.format_exc()), self.err_tag)
            return False, traceback.format_exc()

    @try_except2_async(is_print=True)
    async def deal_html(self, TModel):
        self.step_info = f"处理解析，通过配置css和xpath进行解析"
        bools, err_info = await self.para_next()
        if not bools:
            return bools, err_info
        callmodel = CallBackModel[TModel](
            para_dicts=self.para_dicts,
            sql_model=self.pm.sql_model,
            redis_all=self.redis_model
        )
        self.deal_model: DealModel = self.callback_deal_html(callmodel)
        return True, {}

    def callback_deal_html(self, callmodel) -> DealModel:
        name = "_".join([self.pm.task_name, self.pm.task_tag, "callback"])
        callback = eval(name)
        return callback(callmodel)
